Skip to content

feat(web): UI polish — composer, model picker, sidebar, settings & remote wizard#92

Merged
cnjack merged 1 commit into
mainfrom
feat/ui-and-remote-polish
Jun 21, 2026
Merged

feat(web): UI polish — composer, model picker, sidebar, settings & remote wizard#92
cnjack merged 1 commit into
mainfrom
feat/ui-and-remote-polish

Conversation

@cnjack

@cnjack cnjack commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Summary

Bundles this session's web UI polish together with the pre-existing uncommitted WIP already in the working tree into a single PR (as requested — "all together"). 128 files changed.

UI changes (this session)

Composer / model picker (web/src/components/ChatInput.vue)

  • Remove the channel/chat-bubble button to the left of Send
  • Flatten the "+", approval-mode and model triggers — transparent with no border at rest, background on hover only
  • Model picker: list only enabled models; tighter rows; darker/larger capability icons for legibility; "Current" label → CheckCircle icon; transparent pinned row; hashed per-provider tile colors (no more washed-out gray); darker search placeholder + footer text; narrower & taller panel
  • Mode selector: Plan tinted green, Full access softened red, flat icons (no tile backgrounds)

Sidebar (Sidebar.vue): remove the redundant archive toggle in the Workspace header
Settings (SettingsDialog.vue): flat row icons (no tile backgrounds); green "online" status dot + text
Remote wizard (RemoteConnectWizard.vue): auto-save the SSH host to config on a successful connect (was opt-in); wider & taller dialog (explicit width, fixing the earlier max-width-only change that had no effect)
i18n: drop the duplicated gear glyph on "Manage models"; replace the stale "autopilot" wording with "full access" (zh-Hans / zh-Hant / ja / ko)

Pre-existing WIP carried along

Already-uncommitted work across internal/* (mode, approval, config, web/acp handlers, sessions, etc.), docs/, the Tauri desktop shell, and icon assets.

Verification

  • go build ./... ✅ passes (exit 0)
  • pnpm -C web run type-check (vue-tsc) ✅ passes

Note: UI changes were verified via type-check + browser CSSOM/computed-style checks; some model-picker states couldn't be screenshotted with live data because the local backend wasn't available in this environment.

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added message queue for submitting prompts while agent is running.
    • Redesigned approval request UI with tool-aware decision cards and inline argument preview.
  • Changed

    • Renamed session modes: "Ask" → "Ask for approval," "Autopilot" → "Full access."
    • Updated color scheme from brand orange to neutral accent throughout UI.
    • Splash screen and desktop shell now respect saved theme preference.
    • Improved desktop shell architecture for better performance separation.
  • Documentation

    • Updated all user guides and configuration documentation to reflect new mode terminology.

… & remote wizard

Bundles the in-progress UI/UX work on the web frontend together with the
supporting backend/desktop WIP already present in the tree.

Composer & model picker (ChatInput.vue):
- Drop the channel/chat-bubble button; flatten the "+", approval-mode and
  model triggers (transparent at rest, background on hover only)
- Model picker: list only enabled models, tighten rows, darker/larger
  capability icons, "当前" tag -> CheckCircle icon, transparent pinned row,
  hashed per-provider tile colors (no more washed-out gray), darker search
  placeholder + footer text, narrower & taller panel
- Mode selector: Plan tinted green, Full access softened red, flat icons

Sidebar: remove the redundant workspace archive toggle
Settings: flat row icons (no tile backgrounds), green "online" status
Remote wizard: auto-save the SSH host to config on connect; wider/taller dialog
i18n: drop the duplicated gear glyph on "Manage models"; replace the stale
"autopilot" wording with "full access" in zh-Hans/zh-Hant/ja/ko

Also carries pre-existing uncommitted work across internal/* (mode, approval,
config, web/acp handlers, sessions), docs/, and the Tauri desktop shell.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 05281fa2-aab1-4aa5-9425-6734c055abc7

📥 Commits

Reviewing files that changed from the base of the PR and between a0b932b and cff60fa.

⛔ Files ignored due to path filters (51)
  • desktop/src-tauri/icons/128x128.png is excluded by !**/*.png
  • desktop/src-tauri/icons/128x128@2x.png is excluded by !**/*.png
  • desktop/src-tauri/icons/32x32.png is excluded by !**/*.png
  • desktop/src-tauri/icons/64x64.png is excluded by !**/*.png
  • desktop/src-tauri/icons/Square107x107Logo.png is excluded by !**/*.png
  • desktop/src-tauri/icons/Square142x142Logo.png is excluded by !**/*.png
  • desktop/src-tauri/icons/Square150x150Logo.png is excluded by !**/*.png
  • desktop/src-tauri/icons/Square284x284Logo.png is excluded by !**/*.png
  • desktop/src-tauri/icons/Square30x30Logo.png is excluded by !**/*.png
  • desktop/src-tauri/icons/Square310x310Logo.png is excluded by !**/*.png
  • desktop/src-tauri/icons/Square44x44Logo.png is excluded by !**/*.png
  • desktop/src-tauri/icons/Square71x71Logo.png is excluded by !**/*.png
  • desktop/src-tauri/icons/Square89x89Logo.png is excluded by !**/*.png
  • desktop/src-tauri/icons/StoreLogo.png is excluded by !**/*.png
  • desktop/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png is excluded by !**/*.png
  • desktop/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • desktop/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png is excluded by !**/*.png
  • desktop/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png is excluded by !**/*.png
  • desktop/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • desktop/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png is excluded by !**/*.png
  • desktop/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png is excluded by !**/*.png
  • desktop/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • desktop/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png is excluded by !**/*.png
  • desktop/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png is excluded by !**/*.png
  • desktop/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • desktop/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png is excluded by !**/*.png
  • desktop/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png is excluded by !**/*.png
  • desktop/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • desktop/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png is excluded by !**/*.png
  • desktop/src-tauri/icons/icon.ico is excluded by !**/*.ico
  • desktop/src-tauri/icons/icon.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-20x20@1x.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-20x20@2x-1.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-20x20@2x.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-20x20@3x.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-29x29@1x.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-29x29@2x-1.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-29x29@2x.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-29x29@3x.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-40x40@1x.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-40x40@2x-1.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-40x40@2x.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-40x40@3x.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-512@2x.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-60x60@2x.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-60x60@3x.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-76x76@1x.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-76x76@2x.png is excluded by !**/*.png
  • desktop/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png is excluded by !**/*.png
  • desktop/src-tauri/icons/tray-template.png is excluded by !**/*.png
  • web/public/icon.svg is excluded by !**/*.svg
📒 Files selected for processing (77)
  • CHANGELOG.md
  • Makefile
  • README.md
  • design/model-and-approval-redesign.html
  • desktop/package.json
  • desktop/splash/index.html
  • desktop/src-tauri/capabilities/default.json
  • desktop/src-tauri/icons/icon.icns
  • desktop/src-tauri/src/main.rs
  • desktop/src-tauri/src/sidecar.rs
  • desktop/src-tauri/src/tray.rs
  • desktop/src-tauri/tauri.conf.json
  • docs/commands.md
  • docs/configuration.md
  • docs/overview/agent.md
  • docs/overview/plan-mode.md
  • docs/overview/sessions.md
  • docs/tools.md
  • docs/web-interface.md
  • internal/command/acp.go
  • internal/command/interactive.go
  • internal/command/mode_helpers_test.go
  • internal/command/web.go
  • internal/config/config.go
  • internal/handler/acp.go
  • internal/handler/web.go
  • internal/handler/web_test.go
  • internal/mode/mode.go
  • internal/mode/mode_test.go
  • internal/runner/approval.go
  • internal/runner/approval_test.go
  • internal/session/history.go
  • internal/session/mode_roundtrip_test.go
  • internal/tui/input_views.go
  • internal/tui/messages.go
  • internal/tui/mode_pill_test.go
  • internal/tui/pickers.go
  • internal/tui/statusbar_component.go
  • internal/tui/styles.go
  • internal/tui/tui.go
  • internal/tui/update.go
  • internal/web/cors_test.go
  • internal/web/frontend.go
  • internal/web/frontend_headless.go
  • internal/web/mode_test.go
  • internal/web/server.go
  • web/src/App.vue
  • web/src/components/ApprovalBanner.vue
  • web/src/components/AskUserCard.vue
  • web/src/components/BranchPicker.vue
  • web/src/components/ChatInput.vue
  • web/src/components/ChatMessage.vue
  • web/src/components/DiffViewer.vue
  • web/src/components/FileTreePanel.vue
  • web/src/components/GoalBanner.vue
  • web/src/components/ProjectSwitcher.vue
  • web/src/components/RemoteConnectWizard.vue
  • web/src/components/RightPanel.vue
  • web/src/components/SettingsDialog.vue
  • web/src/components/Sidebar.vue
  • web/src/components/TaskList.vue
  • web/src/components/TerminalInstance.vue
  • web/src/components/ToolCallCard.vue
  • web/src/components/TopBar.vue
  • web/src/components/WorkspacePicker.vue
  • web/src/composables/api.ts
  • web/src/composables/apiBase.ts
  • web/src/composables/ws.ts
  • web/src/i18n/locales/en.ts
  • web/src/i18n/locales/ja.ts
  • web/src/i18n/locales/ko.ts
  • web/src/i18n/locales/zh-Hans.ts
  • web/src/i18n/locales/zh-Hant.ts
  • web/src/main.ts
  • web/src/stores/chat.ts
  • web/src/styles/tokens.css
  • web/src/types/api.ts

📝 Walkthrough

Walkthrough

Session mode identifiers are renamed from ask/autopilot to approval/full_access throughout the Go backend, TUI, web server, and frontend. The Tauri desktop app is restructured so the frontend stays on its own origin and resolves the Go sidecar's loopback port via a new IPC command. A client-side type-ahead message queue is added to ChatInput. ApprovalBanner is redesigned with a tool-identity card. SettingsDialog adopts unified .s-* design atoms. Neutral accent CSS tokens replace --color-primary across all web components.

Changes

Session Mode Rename, Desktop Sidecar Architecture, Web Queue & UI Redesign

Layer / File(s) Summary
SessionMode enum, wire values, and parse/cycle logic
internal/mode/mode.go, internal/mode/mode_test.go, internal/session/history.go, internal/session/mode_roundtrip_test.go
Renames AskApproval and AutopilotFullAccess constants; updates String(), AutoApprove(), Label(), Next(), Parse(); removes legacy alias parsing; tests updated to match new cycle Approval→Plan→FullAccess→Approval.
ApprovalState and handler mode promotion
internal/runner/approval.go, internal/runner/approval_test.go, internal/handler/acp.go, internal/handler/web.go, internal/handler/web_test.go
Maps autoApprove=true to mode.FullAccess; promotes session to mode.FullAccess on "Approve All" in runner and ACP handler; updates notifyModeChanged call and surrounding comments.
ACP SetSessionMode, ResumeSession, and startup mode resolution
internal/command/acp.go, internal/command/interactive.go, internal/command/mode_helpers_test.go, internal/command/web.go, internal/config/config.go
Replaces ACP mode id constants; tightens SetSessionMode to reject legacy ids; normalizes resumed Plan to Approval; resolveStartupMode maps --unsafe/AutoApprove=true to FullAccess and defaults to Approval.
TUI mode pills, selector cycle, and status bar
internal/tui/tui.go, internal/tui/input_views.go, internal/tui/styles.go, internal/tui/mode_pill_test.go, internal/tui/statusbar_component.go, internal/tui/pickers.go, internal/tui/update.go, internal/tui/messages.go
Updates selectorMode()/applySelectorMode() to use FullAccess/Approval; renames modePillAskStylemodePillApprovalStyle; updates pill labels, statusbar text, and Shift+Tab help text.
Web server mode validation, approve-all sync, and CORS updates
internal/web/server.go, internal/web/mode_test.go, internal/web/cors_test.go, internal/web/frontend.go, internal/web/frontend_headless.go
Tightens handleSwitchMode to canonical ids; adds syncModeAfterApproval that promotes s.mode to full_access and broadcasts mode_changed on approve_all; adds tauri.localhost to CORS allow-list; headless build stub for SPA.
Docs and CHANGELOG mode terminology
CHANGELOG.md, README.md, docs/commands.md, docs/configuration.md, docs/overview/*, docs/tools.md, docs/web-interface.md
Updates all user-facing docs to use Ask for approval/Plan/Full access labels and approval/plan/full_access API values; CHANGELOG entry added noting legacy IDs no longer accepted.
Desktop sidecar: headless build, SidecarPort IPC, tray, and Tauri config
Makefile, desktop/src-tauri/src/sidecar.rs, desktop/src-tauri/src/main.rs, desktop/src-tauri/src/tray.rs, desktop/src-tauri/tauri.conf.json, desktop/src-tauri/capabilities/default.json, desktop/package.json, desktop/splash/index.html
Adds jcode_headless build tag to desktop-sidecar target; introduces SidecarPort Mutex state published before health polling; adds get_sidecar_port IPC command; removes prior webview navigation; tray uses embedded template icon; Tauri config points to web/dist with Vite dev server; capabilities broadened for additional origins; splash reads saved theme.
apiBase composable: browser vs desktop URL resolution
web/src/composables/apiBase.ts, web/src/composables/api.ts, web/src/composables/ws.ts, web/src/components/TerminalInstance.vue, web/src/main.ts
New apiBase.ts exports apiBase, wsBase(), initApiBase() (polls get_sidecar_port IPC then /api/health in desktop mode); api.ts, ws.ts, and TerminalInstance.vue use apiBase/wsBase(); main.ts awaits initApiBase() before mount.
Web frontend mode rename, message queue store, and AgentMode type
web/src/types/api.ts, web/src/stores/chat.ts, web/src/App.vue
AgentMode updated to approval|plan|full_access; store mode default changed to 'approval'; autoApprove derived from mode==='full_access'; adds QueuedMessage, queuedMessages, enqueueMessage/removeQueuedMessage/flushQueue; agentDone drains queue; App.vue WS mode sync updated.
ChatInput: queue UI, mode/model selector rebuild
web/src/components/ChatInput.vue, web/src/components/RemoteConnectWizard.vue
send() enqueues when agent is running; queued messages list with remove controls rendered above composer; modes list replaced with risk-classified approval/plan/full_access entries; toolbar model picker rebuilt with provider identity tiles, search, pinned row, favorites; RemoteConnectWizard always saves SSH alias on bind.
ApprovalBanner tool-identity card redesign
web/src/components/ApprovalBanner.vue
Replaces lock-icon card with ap-card layout: toolIdentity computed maps tool names to icon+verb; primaryTarget parses tool_args JSON; collapsible args toggle; three-button ramp (ap-btn-yes/ap-btn-all/ap-btn-no); full ap-* CSS overhaul.
SettingsDialog .s-* design atoms
web/src/components/SettingsDialog.vue
Rewrites all tabs with unified .s-row/.s-btn/.s-input/.s-switch/.s-seg/.s-chip atoms; adds section count badges; MCP status chips; removes <kbd> from Shortcuts tab; large CSS block defines all new atoms.
Neutral accent tokens and --color-primary migration
web/src/styles/tokens.css, web/src/components/AskUserCard.vue, web/src/components/BranchPicker.vue, web/src/components/ChatMessage.vue, web/src/components/DiffViewer.vue, web/src/components/FileTreePanel.vue, web/src/components/GoalBanner.vue, web/src/components/ProjectSwitcher.vue, web/src/components/RightPanel.vue, web/src/components/Sidebar.vue, web/src/components/TaskList.vue, web/src/components/ToolCallCard.vue, web/src/components/TopBar.vue, web/src/components/WorkspacePicker.vue
Adds --color-accent-neutral, --neutral-wash-*, --neutral-border tokens; migrates all accent interactive states from --color-primary to --color-accent-neutral across all listed components.
i18n locale updates
web/src/i18n/locales/en.ts, web/src/i18n/locales/ja.ts, web/src/i18n/locales/ko.ts, web/src/i18n/locales/zh-Hans.ts, web/src/i18n/locales/zh-Hant.ts
All five locales: adds common.done; adds chat queue strings; replaces ask/autopilot mode labels with approval/plan/fullAccess; expands model selector labels; adds tool action/args strings; updates autoApproveDesc to reference Full access.
Design mockup
design/model-and-approval-redesign.html
Adds self-contained HTML mockup for model selector, mode selector, Manage Models dialog, and approval decision card with theme toggle and interactive tabs.

Sequence Diagram(s)

sequenceDiagram
  participant DesktopWeb as Desktop Web UI
  participant TauriIPC as Tauri IPC
  participant Sidecar as Go Sidecar API
  DesktopWeb->>TauriIPC: invoke get_sidecar_port
  TauriIPC-->>DesktopWeb: return loopback port
  DesktopWeb->>Sidecar: GET /api/health
  Sidecar-->>DesktopWeb: return status ok
  DesktopWeb->>Sidecar: POST /api/approval approve_all=true
  Sidecar-->>DesktopWeb: broadcast mode_changed full_access
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • cnjack/jcode#75: Implements the same unified 3-state session-mode selector across TUI/Web/ACP touching the same internal/mode.SessionMode, mode resolution, and web/ACP/TUI mode sync code paths that this PR renames.
  • cnjack/jcode#76: Both PRs modify the web/Tauri approval workflow to propagate approve_all and synchronize the resulting mode promotion via the WebSocket/server approval resolution code.
  • cnjack/jcode#90: Both PRs touch web/src/components/ApprovalBanner.vue's two-step "Allow all" flow and approval-mode persistence in the same approval/mode wiring area.

Poem

🐰 Hop, hop, the modes have new names today,
No more "Ask" or "Autopilot" in the way!
"Approval," "Plan," "Full access" — three in a row,
The desktop sidecar ports its secrets below.
A queue for your messages, a card for each tool —
The rabbit refactors with style and with cool! ✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/ui-and-remote-polish

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cnjack cnjack merged commit 89fd095 into main Jun 21, 2026
2 of 3 checks passed
@cnjack cnjack deleted the feat/ui-and-remote-polish branch June 21, 2026 16:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant